/**
 * 日期时间处理工具
 */
export const dateUtils = {
  /**
   * 日期格式化
   * @param date Date对象或时间戳
   * @param format 格式字符串，默认'YYYY-MM-DD HH:mm:ss'
   */
  format(date: Date | number, format = 'YYYY-MM-DD HH:mm:ss'): string {
    const d = new Date(date)
    const year = d.getFullYear()
    const month = String(d.getMonth() + 1).padStart(2, '0')
    const day = String(d.getDate()).padStart(2, '0')
    const hours = String(d.getHours()).padStart(2, '0')
    const minutes = String(d.getMinutes()).padStart(2, '0')
    const seconds = String(d.getSeconds()).padStart(2, '0')

    return format
      .replace('YYYY', String(year))
      .replace('MM', month)
      .replace('DD', day)
      .replace('HH', hours)
      .replace('mm', minutes)
      .replace('ss', seconds)
  },

  /**
   * 计算日期差
   * @param start 开始日期
   * @param end 结束日期
   * @param unit 单位: 'day'|'hour'|'minute'|'second'
   */
  diff(start: Date | number, end: Date | number, unit: 'day' | 'hour' | 'minute' | 'second' = 'day'): number {
    const startTime = new Date(start).getTime()
    const endTime = new Date(end).getTime()
    const diff = endTime - startTime

    switch (unit) {
      case 'day': return Math.floor(diff / (1000 * 60 * 60 * 24))
      case 'hour': return Math.floor(diff / (1000 * 60 * 60))
      case 'minute': return Math.floor(diff / (1000 * 60))
      case 'second': return Math.floor(diff / 1000)
      default: return diff
    }
  },

  /**
   * 添加时间
   * @param date 基准日期
   * @param value 要添加的值
   * @param unit 单位: 'year'|'month'|'day'|'hour'|'minute'|'second'
   */
  add(date: Date | number, value: number, unit: 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second'): Date {
    const d = new Date(date)
    switch (unit) {
      case 'year': d.setFullYear(d.getFullYear() + value); break
      case 'month': d.setMonth(d.getMonth() + value); break
      case 'day': d.setDate(d.getDate() + value); break
      case 'hour': d.setHours(d.getHours() + value); break
      case 'minute': d.setMinutes(d.getMinutes() + value); break
      case 'second': d.setSeconds(d.getSeconds() + value); break
    }
    return d
  }
}

/**
 * 增强型本地存储操作
 */
export const storage = {
  set(key: string, value: any, expire?: number): void {
    const data = {
      value,
      expire: expire ? Date.now() + expire * 1000 : undefined
    }
    uni.setStorageSync(key, JSON.stringify(data))
  },

  get<T>(key: string): T | null {
    const dataStr = uni.getStorageSync(key)
    if (!dataStr) return null

    try {
      const data = JSON.parse(dataStr)
      if (data.expire && Date.now() > data.expire) {
        this.remove(key)
        return null
      }
      return data.value
    } catch {
      return null
    }
  },

  remove(key: string): void {
    uni.removeStorageSync(key)
  },

  clear(): void {
    uni.clearStorageSync()
  },

  getInfo(): UniApp.StorageInfo {
    return uni.getStorageInfoSync()
  }
}

/**
 * 验证工具集
 */
export const validator = {
  isPhone(phone: string): boolean {
    return /^1[3-9]\d{9}$/.test(phone)
  },

  isEmail(email: string): boolean {
    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
  },

  isIdCard(id: string): boolean {
    return /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/.test(id)
  },

  isUrl(url: string): boolean {
    return /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*)$/.test(url)
  }
}

/**
 * 设备信息工具
 */
export const device = {
  getInfo(): Promise<UniApp.GetSystemInfoResult> {
    return new Promise((resolve) => {
      uni.getSystemInfo({
        success: resolve
      })
    })
  },

  getNetworkType(): Promise<UniApp.GetNetworkTypeSuccess> {
    return new Promise((resolve) => {
      uni.getNetworkType({
        success: resolve
      })
    })
  },

  getBatteryInfo(): Promise<UniApp.GetBatteryInfoSuccess> {
    return new Promise((resolve) => {
      uni.getBatteryInfo({
        success: resolve
      })
    })
  }
}

/**
 * 性能监控工具
 */
export const performance = {
  mark(name: string): void {
    // #ifdef APP-PLUS
    plus.performance.mark(name)
    // #endif
  },

  measure(startMark: string, endMark: string): number | null {
    // #ifdef APP-PLUS
    const result = plus.performance.measure(startMark, endMark)
    return result.duration
    // #else
    return null
    // #endif
  },

  time(callback: () => void): number {
    const start = Date.now()
    callback()
    return Date.now() - start
  }
}

/**
 * 函数工具集
 */
export const func = {
  debounce(fn: Function, delay = 300): Function {
    let timer: number | null = null
    return function (this: any, ...args: any[]) {
      if (timer) {
        clearTimeout(timer)
      }
      timer = setTimeout(() => {
        fn.apply(this, args)
        timer = null
      }, delay)
    }
  },

  throttle(fn: Function, delay = 300): Function {
    let lastTime = 0
    return function (this: any, ...args: any[]) {
      const now = Date.now()
      if (now - lastTime >= delay) {
        fn.apply(this, args)
        lastTime = now
      }
    }
  },

  once(fn: Function): Function {
    let called = false
    return function (this: any, ...args: any[]) {
      if (!called) {
        called = true
        return fn.apply(this, args)
      }
    }
  }
}

/**
 * 生成随机字符串
 * @param length 长度，默认16
 * @param type 类型: 'number'|'letter'|'mixed'，默认'mixed'
 */
export function randomString(length = 16, type: 'number' | 'letter' | 'mixed' = 'mixed'): string {
  let chars = ''
  if (type === 'number') chars = '0123456789'
  else if (type === 'letter') chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
  else chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'

  let result = ''
  for (let i = 0; i < length; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length))
  }
  return result
}